package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusBpmnInfo;
import cn.wolfcode.business.domain.BusCarPackageAudit;
import cn.wolfcode.business.domain.BusServiceItem;
import cn.wolfcode.business.domain.vo.CarPackageAuditIVO;
import cn.wolfcode.business.domain.vo.HistoryVo;
import cn.wolfcode.business.mapper.BusBpmnInfoMapper;
import cn.wolfcode.business.mapper.BusCarPackageAuditMapper;
import cn.wolfcode.business.service.IBusCarPackageAuditService;
import cn.wolfcode.business.service.IBusServiceItemService;
import cn.wolfcode.business.util.DateUtil;
import cn.wolfcode.common.utils.SecurityUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.*;

@Service
public class BusCarPackageAuditServiceImpl implements IBusCarPackageAuditService {
    @Autowired
    private BusCarPackageAuditMapper busCarPackageAuditMapper;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private IBusServiceItemService busServiceItemService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private BusBpmnInfoMapper busBpmnInfoMapper;


    @Override
    public List<BusCarPackageAudit> selectBusCarPackageAuditList(BusCarPackageAudit busCarPackageAudit) {
        Map<String, Object> map = busCarPackageAudit.getParams();
        if (map != null) {
            String endCreateTime = (String) map.get("endCreateTime");
            if (endCreateTime != null) {
                map.put("endCreateTime", endCreateTime + " 23:59:59");
            }
        }
        return busCarPackageAuditMapper.selectBusCarPackageAuditList(busCarPackageAudit);
    }

    @Override
    public void insert(BusCarPackageAudit busCarPackageAudit) {
        busCarPackageAudit.setCreateTime(new Date());
        busCarPackageAuditMapper.insert(busCarPackageAudit);
    }

    @Override
    public void update(BusCarPackageAudit busCarPackageAudit) {
        busCarPackageAuditMapper.update(busCarPackageAudit);
    }

    @Override
    public InputStream processImg(Long instanceId) {
        if (instanceId==null){
            throw new RuntimeException("非法参数");
        }
        BpmnModel bpmnModel = null;
        List<String> activeActivityIds = new ArrayList<>();
        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(instanceId.toString())
                .singleResult();
        if (processInstance == null) {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(instanceId.toString())
                    .singleResult();
            bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        }else{
            bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
            activeActivityIds = runtimeService.getActiveActivityIds(instanceId.toString());
        }
        InputStream inputStream = generator.generateDiagram(
                bpmnModel,
                activeActivityIds,
                Collections.emptyList(),
                "宋体",
                "宋体",
                "宋体"
        );
        return inputStream;

    }

    @Override
    @Transactional
    public int deleteBusCarPackageAuditById(Long id) {
        if (id==null){
            throw new RuntimeException("非法参数");
        }
        BusCarPackageAudit busCarPackageAudit = busCarPackageAuditMapper.selectById(id);
        if (busCarPackageAudit==null){
            throw new RuntimeException("非法参数");
        }
        if (!BusCarPackageAudit.STATUS_IN_PROGRESS.equals(busCarPackageAudit.getStatus())){
            throw new RuntimeException("只有审批中才能进行撤销操作");
        }
        busCarPackageAuditMapper.updateStatus(id,BusCarPackageAudit.STATUS_CANCEL);
        runtimeService.deleteProcessInstance(busCarPackageAudit.getInstanceId(),"撤销");
        return busServiceItemService.updateStatus(busCarPackageAudit.getServiceItemId(),BusServiceItem.AUDITSTATUS_INIT);
    }

    @Override
    public List<HistoryVo> selectHistoryList(Long instanceId) {
        if (instanceId==null){
            throw new RuntimeException("非法参数");
        }
        List<HistoricTaskInstance> history = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(instanceId.toString())
                .list();

        List<HistoryVo> list = history.stream().map(historicTaskInstance -> {
            HistoryVo historyVo = new HistoryVo();
            historyVo.setTaskName(historicTaskInstance.getName());
            historyVo.setStartTime(DateUtil.Date2String(historicTaskInstance.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
            if (historicTaskInstance.getEndTime() != null && historicTaskInstance.getDurationInMillis() != null) {
                historyVo.setEndTime(DateUtil.Date2String(historicTaskInstance.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
                historyVo.setDurationInMillis(historicTaskInstance.getDurationInMillis() / 6000 + "s");
            }
            List<Comment> taskComments = taskService.getTaskComments(historicTaskInstance.getId());
            if (taskComments != null && !taskComments.isEmpty()) {
                for (Comment taskComment : taskComments) {
                    historyVo.setComment(taskComment.getFullMessage());
                }
            }
            return historyVo;
        }).toList();
        return list;
    }

    @Override
    public List<BusCarPackageAudit> selecttodoTaskList(BusCarPackageAudit busCarPackageAudit) {
        Long userId = SecurityUtils.getUserId();
        BusBpmnInfo busBpmnInfo = busBpmnInfoMapper.selectType(BusCarPackageAudit.FLOW_AUDIT_TYPE);
        List<Task> tasks = taskService.createTaskQuery()
                .processDefinitionKey(busBpmnInfo.getProcessDefinitionKey())
                .taskAssignee(userId.toString())
                .list();
        if (tasks==null || tasks.isEmpty()){
            return Collections.emptyList();
        }
        List<String> list = tasks.stream().map(instanceIdList -> {
            return instanceIdList.getProcessInstanceId();
        }).toList();
        if (list!=null && !list.isEmpty()){
            busCarPackageAudit.getParams().put("instanceIdList",list);
        }


        return busCarPackageAuditMapper.selectBusCarPackageAuditList(busCarPackageAudit);
    }

    @Override
    @Transactional
    public int audit(CarPackageAuditIVO carPackageAuditIVO) {
        if (carPackageAuditIVO==null){
            throw new RuntimeException("非法参数");
        }
        BusCarPackageAudit busCarPackageAudit = busCarPackageAuditMapper.selectById(carPackageAuditIVO.getId());
        if (busCarPackageAudit==null){
            throw new RuntimeException("非法参数");
        }
        if(!BusCarPackageAudit.STATUS_IN_PROGRESS.equals(busCarPackageAudit.getStatus())){
            throw new RuntimeException("当前状态不允许审核");
        }
        String instanceId = busCarPackageAudit.getInstanceId();
        Long userId = SecurityUtils.getUserId();
        Task task = taskService.createTaskQuery()
                .processInstanceId(instanceId)
                .taskAssignee(userId.toString())
                .singleResult();
        if (task==null){
            throw new RuntimeException("非法参数");
        }
        StringBuilder msg = new StringBuilder("审批人");
        msg.append(SecurityUtils.getUsername());
        boolean audit = BusCarPackageAudit.STATUS_PASS.equals(carPackageAuditIVO.getAuditStatus());
        if (audit){
            msg.append("审批人同意[");
        }else {
            msg.append("审批人拒绝[");
        }
        msg.append(carPackageAuditIVO.getAuditInfo()).append("]");
        taskService.addComment(task.getId(),instanceId,msg.toString());
        int count = 0;
        Map<String,Object> map = new HashMap<>();
        map.put("shopOwner",audit);
        if (audit){
            map.put("disCountPrice",busCarPackageAudit.getServiceItemPrice().doubleValue());
        }
        taskService.complete(task.getId(),map);

        if (audit){
            List<Task> tasks = taskService.createTaskQuery()
                    .processInstanceId(instanceId)
                    .list();
            if (tasks.isEmpty() || tasks == null){
                busCarPackageAuditMapper.updateStatus(busCarPackageAudit.getId(),BusCarPackageAudit.STATUS_PASS);
                count = busServiceItemService.updateStatus(busCarPackageAudit.getServiceItemId(),BusServiceItem.AUDITSTATUS_APPROVED);
            }else {
                return 1;
            }
        }else {
            busCarPackageAuditMapper.updateStatus(busCarPackageAudit.getId(),BusCarPackageAudit.STATUS_REJECT);
            count = busServiceItemService.updateStatus(busCarPackageAudit.getServiceItemId(),BusServiceItem.AUDITSTATUS_REPLY);
        }
        return count;
    }

    @Override
    public List<BusCarPackageAudit> selectDoneTask(BusCarPackageAudit busCarPackageAudit) {
        Long userId = SecurityUtils.getUserId();
        BusBpmnInfo busBpmnInfo = busBpmnInfoMapper.selectType(BusCarPackageAudit.FLOW_AUDIT_TYPE);
        List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey(busBpmnInfo.getProcessDefinitionKey())
                .taskAssignee(userId.toString())
                .list();
        if (tasks==null || tasks.isEmpty()){
            return Collections.emptyList();
        }
        List<String> list = tasks.stream().map(instanceIdList -> {
            return instanceIdList.getProcessInstanceId();
        }).toList();
        if (list!=null && !list.isEmpty()){
            busCarPackageAudit.getParams().put("instanceIdList",list);
        }


        return busCarPackageAuditMapper.selectBusCarPackageAuditList(busCarPackageAudit);
    }


}
